/** 
 * 并发请求
 * 并发请求的目的是为了提高请求效率
 * 并发请求的实现方式有：
 * 1. 回调函数
 * 2. Promise
 * 3. async/await
 */

class ConcurrentRequest {
  constructor(maxConcurrent = 3) {
    this.maxConcurrent = maxConcurrent; // 最大并发数
    this.queue = []; // 请求队列
    this.activeCount = 0; // 当前活跃请求数
  }

  /**
   * 添加请求到队列
   * @param {Function} task 返回Promise的异步函数
   * @returns {Promise} 返回任务执行结果的Promise
   */
  add(task) {
    return new Promise((resolve, reject) => {
      // 将任务和resolve/reject一起存入队列
      this.queue.push({
        task,
        resolve,
        reject
      });
      // 尝试执行
      this._run();
    });
  }

  /**
   * 执行队列中的任务
   */
  _run() {
    // 如果达到最大并发数或队列为空，则停止
    if (this.activeCount >= this.maxConcurrent || this.queue.length === 0) {
      return;
    }

    // 从队列中取出一个任务
    const { task, resolve, reject } = this.queue.shift();
    this.activeCount++;

    // 执行任务
    const promise = Promise.resolve(task());
    
    promise
      .then(resolve)
      .catch(reject)
      .finally(() => {
        this.activeCount--;
        this._run(); // 一个任务完成后，继续执行下一个
      });
  }
}